package com.xinyue.game.gateway.rocketmq;

import org.apache.rocketmq.client.apis.ClientConfiguration;
import org.apache.rocketmq.client.apis.ClientConfigurationBuilder;
import org.apache.rocketmq.client.apis.ClientException;
import org.apache.rocketmq.client.apis.ClientServiceProvider;
import org.apache.rocketmq.client.apis.message.Message;
import org.apache.rocketmq.client.apis.producer.Producer;
import org.apache.rocketmq.client.apis.producer.SendReceipt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xinyue.game.gateway.common.GameGatewayConfig;

import io.netty.buffer.ByteBuf;

/**
 * 消息队列的客户端服务，用来向消息队列服务发送消息
 *
 * @author 王广帅
 * @since 2023/6/28 20:55
 **/
@Service
public class RocketMQClientService {

    private static final Logger logger = LoggerFactory.getLogger(RocketMQClientService.class);

    @Autowired
    private GameGatewayConfig gameGatewayConfig;

    /**
     * 向消息队列中发送消息
     *
     * @param topic     消息队列主题名称
     * @param selectKey 选择队列的关键字，hash值相同的消息将被发送到同一个队列之中
     * @param byteBuf   要发送的消息
     */
    public void sendMsg(String topic, String selectKey, ByteBuf byteBuf) {
        int len = byteBuf.readableBytes();
        byte[] bytes = new byte[len];
        byteBuf.readBytes(bytes);
        this.sendMsg(topic, selectKey, bytes);
    }

    /**
     * 向消息队列中发送消息
     *
     * @param topic     消息队列主题名称
     * @param selectKey 选择队列的关键字，hash值相同的消息将被发送到同一个队列之中
     * @param byteBuf   要发送的消息
     */
    public void sendMsg(String topic, String selectKey, byte[] byteBuf) {

        String endpoint = gameGatewayConfig.getRocketmqServer();
        ClientServiceProvider provider = ClientServiceProvider.loadService();
        ClientConfigurationBuilder builder = ClientConfiguration.newBuilder().setEndpoints(endpoint);
        ClientConfiguration configuration = builder.build();
        // 初始化Producer时需要设置通信配置以及预绑定的Topic。
        Producer producer = provider.newProducerBuilder()
                .setTopics(topic)
                .setClientConfiguration(configuration)
                .build();
        // 普通消息发送。
        Message message = provider.newMessageBuilder()
                .setTopic(topic)
                // 设置消息索引键，可根据关键字精确查找某条消息。
                .setKeys("messageKey")
                // 设置消息Tag，用于消费端根据指定Tag过滤消息。
                .setTag("messageTag")
                // 消息体。
                .setBody("messageBody".getBytes())
                .build();
        try {
            // 发送消息，需要关注发送结果，并捕获失败等异常。
            SendReceipt sendReceipt = producer.send(message);
            logger.info("Send message successfully, messageId={}", sendReceipt.getMessageId());
        } catch (ClientException e) {
            logger.error("Failed to send message", e);
        }

    }
}
